package se.webbzon.boltzmann.game.npc;

import se.webbzon.boltzmann.game.character.CharacterActionEnum;
import se.webbzon.boltzmann.game.object.player.AbstractPlayerCharacter;
import se.webbzon.boltzmann.npc.AbstractNPC;
import se.webbzon.boltzmann.npc.NPCDuty;
import se.webbzon.oschi01.worldobject.WorldStaticObject;

public class GuardingDuty extends NPCDuty {
	
	// The priority of this duty
	private static final int priority = 0;
	
	// The instance guarded by this duty
	private WorldStaticObject guarded;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public GuardingDuty(AbstractNPC npc) {
		this(npc,null);
	}

	public GuardingDuty(AbstractNPC npc, WorldStaticObject guarded) {
		super(priority, npc);
		this.guarded = guarded;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the instance guarded by this guarding duty. **/
	public WorldStaticObject getGuardedInstance() {
		return guarded;
	}
	
	/** Sets the instance guarded by this guarding duty. **/
	public void setGuardedInstance(WorldStaticObject guarded) {
		this.guarded = guarded;
	}

	@Override public void onBegin() {
		AbstractNPC npc = getNPC();
		setOrigin(npc.getX(),npc.getY(),npc.getZ());
	}

	@Override public void onStep() {
		AbstractNPC npc = getNPC();
		if (guarded != null && npc instanceof GameNPC) {
			GameNPC gameNPC = (GameNPC) npc;
			
			if (!gameNPC.getPlayers().isEmpty()) {
				AbstractPlayerCharacter player = gameNPC.closestPlayer();
				final double v = guarded.getAngle();
				final double phi = Math.atan2(player.getZ() - guarded.getZ(), player.getX() - guarded.getX());
				final double x0 = guarded.getWidth() * Math.cos(phi + v);
				final double z0 = guarded.getDepth() * Math.sin(phi + v);
				final double r = 0.5 * Math.hypot(x0, z0);
				final double x = guarded.getX() + r * Math.cos(phi);
				final double z = guarded.getZ() + r * Math.sin(phi);
				if (npc.getX() == x && npc.getZ() == z) {
					npc.setAction(CharacterActionEnum.STAND);
				} else {
					npc.setAction(CharacterActionEnum.WALK);
					npc.setPosition(x, npc.getY(), z);
				}
			}
		}
	}

	@Override public void onEnd() {};

}
